Daily Excercise 21

Ecosystem Science and Sustainability 330

Author

Madi Schartz

Published

April 21, 2025

Download streamflow data from USGS

# load in necessary packages
library(dataRetrieval)
Warning: package 'dataRetrieval' was built under R version 4.4.3
library(tidymodels)
── Attaching packages ────────────────────────────────────── tidymodels 1.2.0 ──
✔ broom        1.0.7     ✔ recipes      1.1.1
✔ dials        1.3.0     ✔ rsample      1.2.1
✔ dplyr        1.1.4     ✔ tibble       3.2.1
✔ ggplot2      3.5.1     ✔ tidyr        1.3.1
✔ infer        1.0.7     ✔ tune         1.2.1
✔ modeldata    1.4.0     ✔ workflows    1.1.4
✔ parsnip      1.2.1     ✔ workflowsets 1.1.0
✔ purrr        1.0.2     ✔ yardstick    1.3.2
Warning: package 'recipes' was built under R version 4.4.3
── Conflicts ───────────────────────────────────────── tidymodels_conflicts() ──
✖ purrr::discard() masks scales::discard()
✖ dplyr::filter()  masks stats::filter()
✖ dplyr::lag()     masks stats::lag()
✖ recipes::step()  masks stats::step()
• Learn how to get started at https://www.tidymodels.org/start/
library(dplyr)
library(tidyverse)
Warning: package 'lubridate' was built under R version 4.4.3
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ forcats   1.0.0     ✔ readr     2.1.5
✔ lubridate 1.9.4     ✔ stringr   1.5.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ readr::col_factor() masks scales::col_factor()
✖ purrr::discard()    masks scales::discard()
✖ dplyr::filter()     masks stats::filter()
✖ stringr::fixed()    masks recipes::fixed()
✖ dplyr::lag()        masks stats::lag()
✖ readr::spec()       masks yardstick::spec()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tsibble)
Warning: package 'tsibble' was built under R version 4.4.3
Registered S3 method overwritten by 'tsibble':
  method               from 
  as_tibble.grouped_df dplyr

Attaching package: 'tsibble'

The following object is masked from 'package:lubridate':

    interval

The following objects are masked from 'package:base':

    intersect, setdiff, union
# Example: Cache la Poudre River at Mouth (USGS site 06752260)
poudre_flow <- readNWISdv(siteNumber = "06752260",    # Download data from USGS for site 06752260
                          parameterCd = "00060",      # Parameter code 00060 = discharge in cfs)
                          startDate = "2013-01-01",   # Set the start date
                          endDate = "2023-12-31") |>  # Set the end date
  renameNWISColumns() |>                              # Rename columns to standard names (e.g., "Flow", "Date")
  mutate(Date = yearmonth(Date)) |>                   # Convert daily Date values into a year-month format (e.g., "2023 Jan")
  group_by(Date) |>                                   # Group the data by the new monthly Date
  summarise(Flow = mean(Flow))                       # Calculate the average daily flow for each month
GET:https://waterservices.usgs.gov/nwis/dv/?site=06752260&format=waterml%2C1.1&ParameterCd=00060&StatCd=00003&startDT=2013-01-01&endDT=2023-12-31

1. Convert to tsibble

# Convert to tsibble (monthly data, with Date as index)
poudre_ts <- poudre_flow |> 
  as_tsibble(index = Date)

2. Plotting the time series

library(ggplot2)
library(plotly)
Warning: package 'plotly' was built under R version 4.4.3

Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
# Basic ggplot of flow over time
p <- ggplot(poudre_ts, aes(x = Date, y = Flow)) +
  geom_line(color = "navyblue") +
  labs(title = "Monthly Average Flow of Cache la Poudre River",
       y = "Flow (cfs)", x = "Date") +
  theme_minimal()

# Animate with plotly
ggplotly(p)

3. Subseries

library(feasts)
Warning: package 'feasts' was built under R version 4.4.3
Loading required package: fabletools
Warning: package 'fabletools' was built under R version 4.4.3

Attaching package: 'fabletools'
The following object is masked from 'package:yardstick':

    accuracy
The following object is masked from 'package:parsnip':

    null_model
The following objects are masked from 'package:infer':

    generate, hypothesize
# use gg_subseries to visualize the data
subseries_plot <- poudre_ts %>%
  gg_subseries(Flow) +
  labs(title = "Monthly Subseries of Poudre River Flow") +
  theme_minimal()

print(subseries_plot)

4. Decompose

library(fabletools)

# STL decomposition with a seasonal window (say 13 months for annual seasonality)
decomp <- poudre_ts |> 
  model(STL(Flow ~ season(window = "periodic"))) |> 
  components()

# Plot the components
autoplot(decomp)